package org.dromara.solonplugins.nutzdao.integration;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.sql.DataSource;

import org.noear.solon.Utils;
import org.noear.solon.core.BeanWrap;
import org.noear.solon.core.Props;
import org.noear.solon.core.event.EventBus;
import org.noear.solon.core.util.ClassUtil;
import org.nutz.dao.Dao;
import org.nutz.dao.SqlManager;
import org.nutz.dao.entity.EntityMaker;
import org.nutz.dao.impl.FileSqlManager;
import org.nutz.dao.impl.NutDao;

/**
 * activerecord 配置项 管理工具
 * 
 * @author xls-web (小xu中年)
 * @since 2023-11-01
 * */
public class DbManager {
	
	private static final String TAG = "nutzdao";

    private static final String ATTR_enable = "enable";// 是否启用
//    private static final String ATTR_file = "file";// 当sqlManager设置为FileSqlManager时生效
    private static final String ATTR_file_paths = "file.paths";//数组型，sql文件路径
    private static final String ATTR_file_allowDuplicate = "file.allowDuplicate";//是否允许冲突
    private static final String ATTR_file_pairBegin = "file.pairBegin";//
    private static final String ATTR_file_pairEnd = "file.pairEnd";//
    private static final String ATTR_file_regex = "file.regex";//
    private static final String ATTR_file_byRow = "file.byRow";//
    
    private static final String ATTR_entityMaker ="entityMaker";//EntityMaker
    private static final String ATTR_sqlManager ="sqlManager";//自定 SQL 的管理接口

    
    private static final Map<String, Dao> cached = new ConcurrentHashMap<>();
    
    /**
     * 获取管理器
     * @return 暂时默认是NutzDao类型
     */
    public static Dao get(BeanWrap dsWrap) {
        if (dsWrap == null) {
            return null;
        }

        Dao tmp = cached.get(dsWrap.name());
        if (tmp == null) {
            synchronized (dsWrap.name().intern()) {
                tmp = cached.get(dsWrap.name());
                if (tmp == null) {
                    tmp = build(dsWrap);
                    cached.put(dsWrap.name(), tmp);
                }
            }
        }
        
        
        return tmp;
    }
    
    /**
     * 注册管理器
     */
    public static void reg(BeanWrap bw) {
    	get(bw);
    }
    
    /**
     * 清空缓存
     */
    public static void clear() {
    	cached.clear();
    }
    
    /**
     * 构建
     */
    private static Dao build(BeanWrap bw) {
        DataSource master = bw.raw();
        Props dsProps;
       
        if (Utils.isNotEmpty(bw.name())) {
            dsProps = bw.context().cfg().getProp(TAG + "." + bw.name());
        } else {
            dsProps = new Props();
        }
        
        boolean enabled = dsProps.getBool(ATTR_enable, true);//默认是启用的
        dsProps.remove(ATTR_enable);
        if(!enabled) {
        	return null;
        }
         //as bean name
//        String dataSourceId = "ds-" + (bw.name() == null ? "" : bw.name());
        
        String em = dsProps.get(ATTR_entityMaker);
        EntityMaker eMaker = buildEntityMaker(em);
        dsProps.remove(ATTR_entityMaker);
        NutDao nd = null;
        if(eMaker!=null) {
        	nd = new NutDao(master,eMaker);
        }else {
        	nd = new NutDao(master);
        }
        String sqlManager = dsProps.get(ATTR_sqlManager);
        dsProps.remove(ATTR_sqlManager);
        bulidSqlManager(nd,sqlManager,dsProps);
        
        //推到事件中心，用于扩展
        EventBus.publish(nd);
//        arp.start();
        return nd;
    }
    
    private static void bulidSqlManager(NutDao dao, String sqlManager,Props dsProps) {
    	if(Utils.isNotBlank(sqlManager)) {
    		SqlManager sm = null;
    		if(sqlManager.indexOf(".")>0) {
    			sm = ClassUtil.tryInstance(sqlManager);
    		}else {
    			sqlManager = sqlManager.toLowerCase();
    			switch (sqlManager) {
				case "file":
					FileSqlManager fsm = new FileSqlManager();
					List<String> paths = dsProps.getList(ATTR_file_paths);
					if(paths!=null && paths.size()>0) {
						fsm.setPaths(paths.toArray(new String[paths.size()]));
					}
					dsProps.remove(ATTR_file_paths);
					fsm.setAllowDuplicate(dsProps.getBool(ATTR_file_allowDuplicate, true));
					dsProps.remove(ATTR_file_allowDuplicate);
					
					String pairBegin = dsProps.get(ATTR_file_pairBegin);
					if(Utils.isNotBlank(pairBegin)) {
						fsm.setPairBegin(pairBegin);
					}
					dsProps.remove(ATTR_file_pairBegin);
					
					String pairEnd = dsProps.get(ATTR_file_pairEnd);
					if(Utils.isNotBlank(pairEnd)) {
						fsm.setPairEnd(pairEnd);
					}
					dsProps.remove(ATTR_file_pairEnd);
					
					String regex = dsProps.get(ATTR_file_regex);
					if(Utils.isNotBlank(regex)) {
						fsm.setRegex(regex);
					}
					dsProps.remove(ATTR_file_regex);
					
					fsm.setByRow(dsProps.getBool(ATTR_file_byRow, false));
					dsProps.remove(ATTR_file_byRow);
					
					sm = fsm;
					break;

				default:
					break;
				}
    		}
    		if(sm!=null) {
    			dao.setSqlManager(sm);
    		}
    	}
    }
    
    /**
     * EntityMaker
     * @param entityMaker
     */
    private static EntityMaker buildEntityMaker(String entityMaker) {
    	EntityMaker em = null;
    	if(Utils.isNotBlank(entityMaker)) {
    		if(entityMaker.indexOf(".")>0) {
    			em = ClassUtil.tryInstance(entityMaker);
    		}
    	}
    	return em;
    }
	
}
